package com.sky.service.impl;

import com.sky.entity.Orders;
import com.sky.mapper.ReportMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.StringUtil;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.WatchService;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static java.lang.Integer.sum;

/**
 * 数据统计业务层
 */
@Service
@Slf4j
public class ReportServiceImpl implements ReportService {
    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private WorkspaceService workspaceService;


    /**
     * 营业额统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        while (begin.isBefore(end)) {
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        dateList.add(end);
        //根据日期查询营业额
        List<Long> countList = new ArrayList<>();
        Integer status = Orders.COMPLETED;
        for (LocalDate date : dateList) {
            Long count= reportMapper.getAmountByDate(date,status);
            //若营业额为null，转成0，防止没有折线
            if (count==null){
                count=0L;
            }
            countList.add(count);
        }
        String date = StringUtils.join(dateList,",");
        String turnoverList = StringUtils.join(countList, ",");
        TurnoverReportVO turnoverReportVO = new TurnoverReportVO();
        turnoverReportVO.setDateList(date);
        turnoverReportVO.setTurnoverList(turnoverList);
        return turnoverReportVO;
    }

    /**
     * 用户统计
     * @param begin
     * @param end
     * @return
     */
    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList<>();
        while (begin.isBefore(end)) {
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        dateList.add(end);
        List<Long> newUser = new ArrayList<>();
        List<Long> totalUser = new ArrayList<>();
        Long total = reportMapper.getTotalUserByDate(begin);
        for (LocalDate date : dateList) {
            //根据日期查询每天的用户数
            Long user=reportMapper.getUserByDate(date);
            total+=user;
            if (user==null){
                user=0L;
            }
            newUser.add(user);
            totalUser.add(total);
        }
        String date = StringUtils.join(dateList,",");
        String newUsers = StringUtils.join(newUser, ",");
        String totalUsers = StringUtils.join(totalUser, ",");
        UserReportVO userReportVO = new UserReportVO();
        userReportVO.setDateList(date);
        userReportVO.setNewUserList(newUsers);
        userReportVO.setTotalUserList(totalUsers);
        return userReportVO;
    }

    /**
     * 订单统计
     * @param begin
     * @param end
     * @return
     */
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        //将日期封装为集合
        List<LocalDate> dateList = new ArrayList<>();
        while (begin.isBefore(end)) {
            dateList.add(begin);
            begin = begin.plusDays(1);
        }
        dateList.add(end);
        //查询订单数和有效订单数，封装成list
        Integer status = Orders.COMPLETED;
        List<Long> orderCounts = new ArrayList<>();
        List<Long> validOrderCounts = new ArrayList<>();
        for (LocalDate date : dateList) {
            Long orderCount=reportMapper.orderCount(date);
            Long validOrderCount = reportMapper.validOrderCount(date,status);
            orderCounts.add(orderCount);
            validOrderCounts.add(validOrderCount);
        }

        //求订单总数
        Long totalOrderCount = reportMapper.orderCount(null);
        for (Long orderCount : orderCounts) {
            totalOrderCount += orderCount;
        }
        //求有效订单数
        Long totalValidOrderCount = reportMapper.validOrderCount(null,null);
        for (Long validOrderCount : validOrderCounts) {
            totalValidOrderCount += validOrderCount;
        }
        //求订单完成率
        Double orderCompletionRate=0.0;
        if (totalOrderCount!=0) {
            orderCompletionRate = (double)totalValidOrderCount/totalOrderCount;
        }

        //封装
        String date = StringUtils.join(dateList,",");
        String orderCountList = StringUtils.join(orderCounts,",");
        String validOrderCountList = StringUtils.join(validOrderCounts,",");

        OrderReportVO orderReportVO = new OrderReportVO();
        orderReportVO.setDateList(date);
        orderReportVO.setOrderCountList(orderCountList);
        orderReportVO.setValidOrderCountList(validOrderCountList);
        orderReportVO.setOrderCompletionRate(orderCompletionRate);
        orderReportVO.setTotalOrderCount(Math.toIntExact(totalOrderCount));
        orderReportVO.setValidOrderCount(Math.toIntExact(totalValidOrderCount));
        return orderReportVO;
    }

    /**
     * 查询销量排名top10
     * @param begin
     * @param end
     * @return
     */
    @Override
    public SalesTop10ReportVO salesTop10Statistics(LocalDate begin, LocalDate end) {
        List<String> name=reportMapper.getName(begin,end);
        List<Integer> number = reportMapper.getNumber(begin,end);
        SalesTop10ReportVO salesTop10ReportVO = new SalesTop10ReportVO();
        String nameList = StringUtils.join(name, ",");
        String numberList = StringUtils.join(number, ",");
        salesTop10ReportVO.setNameList(nameList);
        salesTop10ReportVO.setNumberList(numberList);
        return salesTop10ReportVO;
    }

    @Override
    public void export(HttpServletResponse response) {
        LocalDate now = LocalDate.now();
        LocalDate begin = now.plusDays(-30);
        LocalDate end = now.plusDays(-1);
        BusinessDataVO businessDatapuls = workspaceService.getBusinessData(LocalDateTime.of(begin, LocalTime.MIN),
                LocalDateTime.of(end, LocalTime.MAX));
        InputStream resourceAsStream =
                this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
        try {
            //填充报表数据
            XSSFWorkbook sheets = new XSSFWorkbook(resourceAsStream);
            XSSFSheet sheetAt = sheets.getSheetAt(0);
            sheetAt.getRow(1).getCell(1).setCellValue(begin+"--"+end+"营业数据");
            sheetAt.getRow(3).getCell(2).setCellValue(businessDatapuls.getTurnover());
            sheetAt.getRow(3).getCell(4).
                    setCellValue(businessDatapuls.getOrderCompletionRate());
            sheetAt.getRow(3).getCell(6).setCellValue(businessDatapuls.getNewUsers());
            sheetAt.getRow(4).getCell(2).setCellValue(businessDatapuls.getValidOrderCount());
            sheetAt.getRow(4).getCell(4).setCellValue(businessDatapuls.getUnitPrice());
            for (int i = 7; i < 37; i++) {
                BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(begin, LocalTime.MIN), LocalDateTime.of(end, LocalTime.MAX));
                XSSFRow row = sheetAt.getRow(i);
                row.getCell(1).setCellValue(String.valueOf(begin));
                row.getCell(2).setCellValue(businessData.getTurnover());
                row.getCell(3).setCellValue(businessData.getValidOrderCount());
                row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessData.getUnitPrice());
                row.getCell(6).setCellValue(businessData.getNewUsers());
                begin=begin.plusDays(1);
            }
            ServletOutputStream outputStream = response.getOutputStream();
            sheets.write(outputStream);
            outputStream.close();
            sheets.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
